package com.kc.data.common.exception;


import com.kc.data.common.base.R;
import com.kc.data.common.base.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import java.util.List;


@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 全局异常.
     *
     * @param e the e
     * @return R
     */
    @ExceptionHandler(Exception.class)
    public R handleGlobalException(Exception e) {
        log.error("全局异常信息 ex={}", e.getMessage(), e);

        return R.failed(e.getLocalizedMessage());
        // return R.failed("系统繁忙，请稍后重试");
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(CustomException.class)
    public R businessException(CustomException e) {
        if (StringUtils.isNull(e.getCode())) {
            return R.failed(e.getMessage());
        }
        return R.restResult(null, e.getCode(), e.getMessage());
    }

    @ExceptionHandler(CustomizeException.class)
    public R handleCommonException(CustomizeException e) {
        log.warn("自定义异常,ex = {}", e.getMessage());
        return R.failed(e.getMessage());
    }


    /**
     * AccessDeniedException
     *
     * @param e the e
     * @return R
     */
//    @ExceptionHandler(AccessDeniedException.class)
//    public R handleAccessDeniedException(AccessDeniedException e) {
//        String msg = SpringSecurityMessageSource.getAccessor().getMessage("AbstractAccessDecisionManager.accessDenied",
//                e.getMessage());
//        log.error("拒绝授权异常信息 ex={}", msg, e);
//        return R.failed(e.getLocalizedMessage());
//    }

    /**
     * validation Exception
     *
     * @param exception
     * @return R
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public R handleBodyValidException(MethodArgumentNotValidException exception) {
        List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
        log.warn("参数绑定异常,ex = {}", fieldErrors.get(0).getDefaultMessage());
        return R.failed(fieldErrors.get(0).getDefaultMessage());
    }
    /**
     * validation Exception
     *
     * @param exception
     * @return R
     */
    @ExceptionHandler({ConstraintViolationException.class})
    public R handleConstraintViolationException(ConstraintViolationException exception) {
        log.warn("参数绑定异常,ex = {}", exception.getMessage());
        return R.failed(exception.getMessage());
    }

    /**
     * validation Exception (以form-data形式传参)
     *
     * @param exception
     * @return R
     */
    @ExceptionHandler({BindException.class})
    public R bindExceptionHandler(BindException exception) {
        List<FieldError> fieldErrors = exception.getBindingResult().getFieldErrors();
        log.warn("参数绑定异常,ex = {}", fieldErrors.get(0).getDefaultMessage());
        return R.failed(fieldErrors.get(0).getDefaultMessage());
    }
}
